package com.yunyao.dao.service.bamu.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yunyao.common.constant.enums.DataDeletedStatus;
import com.yunyao.dao.mapper.BamuContractWirePayMapper;
import com.yunyao.dao.model.BamuContractWirePay;
import com.yunyao.dao.service.bamu.IBamuContractWirePayService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 电线电缆及光纤光缆合同支付方式信息表 服务实现类
 * </p>
 *
 * @author xingjishuai
 * @since 2024-07-02
 */
@Slf4j
@Service
public class BamuContractWirePayServiceImpl extends ServiceImpl<BamuContractWirePayMapper, BamuContractWirePay> implements IBamuContractWirePayService {

    /**
     * 根据合同ID列表查询支付信息列表
     *
     * 此方法的目的是为了通过一批合同ID来获取相应的支付信息，主要应用于需要批量查询支付信息的场景
     * 它通过构建查询包装器来过滤未被删除的支付记录，并且仅返回与提供的合同ID列表相匹配的记录
     *
     * @param contractIdList 合同ID列表，用作查询条件，不能为空
     * @return 返回匹配的支付信息列表，如果输入列表为空，则返回空列表
     */
    @Override
    public List<BamuContractWirePay> listByContractIdList(List<String> contractIdList) {
        // 检查合同ID列表是否为空，如果为空则直接返回空列表
        if (CollectionUtils.isEmpty(contractIdList)) {
            return List.of();
        }
        // 构建查询包装器，用于筛选符合条件的支付记录
        LambdaQueryWrapper<BamuContractWirePay> wrapper = new LambdaQueryWrapper<BamuContractWirePay>()
                // 通过合同ID进行筛选
                .in(BamuContractWirePay::getContractId, contractIdList)
                // 筛选未被删除的记录
                .eq(BamuContractWirePay::getIsDeleted, DataDeletedStatus.NO.getType());
        // 执行查询并返回结果
        return list(wrapper);
    }

    /**
     * 根据合同ID列表将资金支付信息映射为以合同ID为键的映射表
     *
     * @param contractIdList 合同ID列表，用于筛选资金支付信息
     * @return 一个映射表，其中键是合同ID，值是与之对应的资金支付信息对象
     */
    @Override
    public Map<String, BamuContractWirePay> mapByContractIdList(List<String> contractIdList) {
        // 根据提供的合同ID列表获取相应的资金支付信息列表
        List<BamuContractWirePay> wirePayList = listByContractIdList(contractIdList);

        // 如果资金支付信息列表为空，则直接返回一个空的映射表
        if (CollectionUtils.isEmpty(wirePayList)) {
            return Map.of();
        }

        // 使用资金支付信息的合同ID作为键，将资金支付信息列表转换为映射表
        // 如果存在重复的键（即相同的合同ID），则忽略重复的键值对，保留第一个
        return wirePayList.stream().collect(Collectors.toMap(BamuContractWirePay::getContractId, Function.identity(), (o1, o2) -> o1));
    }

    /**
     * 根据合同ID获取BamuContractWirePay信息
     * 此方法用于查询数据库中未被逻辑删除的BamuContractWirePay实体
     *
     * @param contractId 合同ID，用于定位特定的BamuContractWirePay实体
     * @return 如果找到对应的实体且未被逻辑删除，则返回该实体；否则返回null
     */
    @Override
    public BamuContractWirePay getByContractId(String contractId) {
        // 检查contractId是否为空或仅包含空白字符，如果是，则返回null
        if (StringUtils.isBlank(contractId)) {
            return null;
        }

        // 构建查询条件，寻找contractId和isDeleted特定值的实体
        LambdaQueryWrapper<BamuContractWirePay> wrapper =
                new LambdaQueryWrapper<BamuContractWirePay>()
                        .eq(BamuContractWirePay::getContractId, contractId)
                        .eq(BamuContractWirePay::getIsDeleted, DataDeletedStatus.NO.getType());

        // 使用构建的查询条件，从数据库中获取匹配的单个实体
        return getOne(wrapper);
    }

    /**
     * 根据ID软删除合同转账支付信息
     * 通过更新isDeleted字段标记数据为已删除状态，而不是物理删除数据
     *
     * @param id 要删除的合同转账支付的唯一标识
     */
    @Override
    public void deletedById(String id) {
        // 创建一个LambdaUpdateWrapper对象，用于构建更新条件
        // 条件包括：匹配特定ID，并且当前数据未被删除
        LambdaUpdateWrapper<BamuContractWirePay> wrapper =
                new LambdaUpdateWrapper<BamuContractWirePay>()
                        .eq(BamuContractWirePay::getId, id)
                        .eq(BamuContractWirePay::getIsDeleted, DataDeletedStatus.NO.getType())
                        // 设置即将更新的数据字段，将其标记为已删除
                        .set(BamuContractWirePay::getIsDeleted, DataDeletedStatus.YES.getType());
        // 执行更新操作，将符合条件的数据标记为已删除
        update(wrapper);
    }
}
